home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ For TASM / HEAP.PAK / MEM.INC < prev    next >
Text File  |  1996-02-21  |  20KB  |  477 lines

  1. ; FILE: MEM.INC
  2. ; Copyright (c) 1993 By Borland International, Inc.
  3. page
  4.  
  5.  
  6. ;
  7. ; shrink_memory - The main program should call this routine before
  8. ;                initializing any memory system objects. This shrinks
  9. ;                the DOS memory block used by the program to the
  10. ;                minimum possible size.
  11. ;
  12.   global shrink_memory:proc
  13.  
  14.  
  15. ;****************************************************************
  16. ; Memory manager
  17. ; This memory manager supports simple allocation
  18. ; and deallocation of blocks from memory.
  19. ;
  20. ;
  21.  
  22. ; This value is used in the NEXT pointer to indicate a FREE block
  23. FREE_BLOCK = 0FFFFH
  24.  
  25.  
  26. ; Note that the VMT's for the objects in this file must be included in
  27. ; one of the .OBJ's of a project. This is accomplished by the MEM.ASM
  28. ; module defining the following equate before including this file:
  29. ;_MAKE_MEMVMT_ = 1
  30.  
  31. ; Memory_block
  32. ;       A memory block is created for each unit on the heap. Memory
  33. ;   blocks for unused areas of the heap are larger, and contain more
  34. ;   information, than used blocks on the heap. Note that there are
  35. ;   derived classes that handle implementing used_blocks.
  36. ;
  37. ; \/ Not yet implemented
  38. ; initget- Handles getting an extra block of memory from DOS, and
  39. ;          allocating getting it set up. It does not need to be
  40. ;          passed the address of a memory block to init.
  41. ;          This is an example of a constructor that even does it's
  42. ;          own allocation, as well as setting up of VMT.
  43. ;     Arguments:(segments of previous and next blocks)
  44. ;     Returns:   AX segment of block that was allocated
  45. ;
  46. ;
  47. ; init   - Handles initializing a block to an unused state.
  48. ;          Includes setting the VMT pointer to type the block as a
  49. ;          memory_block and it also sets the next pointer and the
  50. ;          size. The previous block pointer is unused since the
  51. ;          memory system does not always find the previous block out
  52. ;          of efficiency considerations.
  53. ;     Arguments:(DS:SI instance ptr), (segments of previous and next blocks)
  54. ;
  55. ;
  56. ; deinit - Handles destruction of the memory block. Currently has no
  57. ;          function for memory_block or memory_usedblock. No protocol
  58. ;          for usage is setup.
  59. ;
  60. ; memstart - Returns fixed offset within memory blocks that marks the
  61. ;            start of information that is only optionally used if the
  62. ;            block is empty. This allows descendants to increase the
  63. ;            amount of bookkeeping information used in the memory_block
  64. ;            for all blocks, free and used.
  65. ;            Users of the memory system only need to store segment
  66. ;            values of alloced blocks, and they can use this function to
  67. ;            fill in the offset if they want.
  68. ;            Of course, this behaviour may not be compatible with future
  69. ;            memory blocks which might not neccessarily return a constant
  70. ;            value for the memstart.
  71. ;     Arguments: None
  72. ;     Returns:   BX  with fixed offset value
  73. ;
  74. ;
  75. ; Show - Shows whether or not the block is free.
  76. ;        If the block is free, additional information concerning the block
  77. ;        is printed, including it's next pointer and the size of the free
  78. ;        area.
  79. ;      Arguments: DS:SI - Address of the memory block
  80. ;
  81. ;
  82. ; MatchNext - Finds the address if the block whose next pointer points
  83. ;             to the given block
  84. ;      Arguments: DS:SI - Address of memory block
  85. ;                 AX    - Segment address of block to find next ptr to.
  86. ;      Returns:   AX    - Segment of memory block that points to the
  87. ;                            given block with next.
  88. ;                         AX=0 if a previous block was not found.
  89. ;                 DS:SI - Changed
  90. ;
  91. ; ScanFree   - If the current block is not free, this routine scans forward
  92. ;              until a free block is free
  93. ;      Arguments: DS:SI - Address of memory block
  94. ;      Returns:   DS:SI - Points to a free block.
  95. ;                         DS=0 if no more free blocks
  96. ;                 AX - Size of block in paragraphs. 0 if not free.
  97. ;                      Size is already adjusted for bookkeeping info.
  98. ;
  99. ;
  100. ; GetNext    - Returns the segment address of the next block.
  101. ;      Arguments: DS:SI - Address of memory block
  102. ;      Returns:   AX    - Segment of next memory block
  103. ;
  104. ;
  105. ; SetNext    - Sets the pointer to the next block
  106. ;      Arguments: DS:SI - Address of memory block
  107. ;                 AX    - Segment of next memory block
  108. ;      Returns:   None
  109. ;
  110. ;
  111. ifdef _DO_SETPREV_
  112. ; SetPrev  - Sets the pointer to the previous memory block. If the
  113. ;            block is in use, this call does nothing.
  114. ;      Arguments: DS:SI - Address of memory block
  115. ;                 AX    - Segment of prev memroy block
  116. ;      Returns:   None
  117. endif
  118. ;
  119. ; SetSize  - Sets the size field of the memory block. If the
  120. ;            block is in use, this call does nothing.
  121. ;      Arguments: DS:SI - Address of memory block
  122. ;                 AX    - Size of the memory block
  123. ;      Returns:   None
  124. ;
  125. ; IsFree
  126. ;      Arguments: DS:SI - Address of the memory block
  127. ;      Returns    Z flag set if the block is free.
  128. ;
  129. ;
  130. ; MarkUsed - Marks the block as used. This is done by copying the
  131. ;            NEXT2 pointer into NEXT. This will erase the FFFF
  132. ;            signature in the NEXT ptr, which will show the
  133. ;            block as used. This does nothing if the block is already
  134. ;            marked as used.
  135. ;
  136. ;      Arguments: DS:SI - Address of the memory block
  137. ;
  138. ; MarkFree - Marks the block as free. This is done by copying the
  139. ;            NEXT pointer into NEXT2, and putting 0FFFFH in NEXT.
  140. ;            Also the size of the block is calculated and filled in.
  141. ;            Also the previous block pointer is filled in.
  142. ;
  143. ;      Arguments: DS:SI - Address of the memory block
  144. ;                 AX    - Previous block
  145. ;
  146. ; RawBlockSize - Returns the total size in paragraphs of the block,
  147. ;                including bookkeeping information. Only works for
  148. ;                blocks that are free.
  149. ;      Arguments: DS:SI - Address of memory block
  150. ;      Returns:   AX
  151. ;
  152. ; BreakBlock - Breaks a free block in two.
  153. ;      Arguments: DS:SI - Address of the memory block
  154. ;                 AX    - New desired size of the block, not counting
  155. ;                         bookkeeping info.
  156. ;      Returns:   AX      Segment address of new free block, if block broken
  157. ;                         off, or returns same as original DS if whole block
  158. ;                         is used.
  159. ;
  160. ; Combine - Combines a block with it's previous block, if both are free.
  161. ;           The previous block is guaranteed to be free if this is called.
  162. ;           Alloc calls this during it's forward walk thru the stack.
  163. ;           Blocks that are not free should ignore this call.
  164. ;      Arguments: DS:SI - Address of the memory block
  165. ;                 AX    - Address of the previous block.
  166. ;      Returns:   DS:SI - Address of the previous block if the combine was
  167. ;                         done, otherwise they are unchanged.
  168. ;
  169. ;
  170. ; LockBlock - Currently not used. This call should be made before using the
  171. ;             contents of a block of memory allocated from the heap. This
  172. ;             routine may return a new address to use as a pointer to the
  173. ;             actual memory contents.
  174. ;             This is automatically called before the ALLOC call terminates.
  175. ;
  176. ; UnLockBlock - Currently not used. This call should be given the value
  177. ;             returned by the UnLockBlock routine.
  178. ;
  179. ; AllocFail - This method is called for all blocks if an allocation
  180. ;             request of the memory system is about to fail. If the
  181. ;             block does nothing with this request, it needs to return
  182. ;             the Z flag set. If it is able to process this request
  183. ;             and cause memory to be freed, or in some other way enable
  184. ;             the memory system to possibly succeed, then it can return
  185. ;             the zero flag unset, and the memory_system will retry the
  186. ;             allocation request.
  187. ;             Example: Diskswapping memory blocks could delay actual
  188. ;             swap out until they recieve this call. Memory blocks and
  189. ;             the controlling swap block should know the location of
  190. ;             each other, so they both can respond to the request.
  191. ;             Blocks that implement memory swapping might even try to
  192. ;             swap out several blocks before returning with the Z flag
  193. ;             unset.
  194.  
  195.  
  196. ; Note the size of PREV & NEXT. Because MASM mode makes all symbols
  197. ;  be global in scope, if other structures define their own PREV or
  198. ;  NEXT pointers, they must be of the same size, and at the same
  199. ;  location within the structure. Since other routines may want
  200. ;  fullsize NEXT and PREV pointers, this structure defines them to be
  201. ;  the same size.... However, a more advanced memory block could
  202. ;  make use of the extra word to implement some sort of disk cacheing
  203. ;  or other use, especially if lock/unlock system is used for all
  204. ;  blocks.
  205. ; Note that FindPrev_ is defined to avoid conflict with memory system
  206. ;  FindPrev routine.
  207. ; Note also show
  208.  
  209.      global  memory_block_initget:proc
  210.      global  memory_block_init:proc
  211.      global  memory_block_deinit:proc
  212.      global  mb_show:proc
  213.      global  memory_block_reserved_size:proc
  214.      global  mb_findprev:proc
  215.      global  mb_scan:proc
  216.      global  mb_getnext:proc
  217.      global  mb_isfree:proc
  218.      global  mb_setprev:proc
  219.      global  mb_setnext:proc
  220.      global  mb_setsize:proc
  221.      global  mb_rawblocksize:proc
  222.      global  mb_breakblock:proc
  223.      global  memory_block_markused:proc
  224.      global  memory_block_combine:proc
  225.      global  memory_block_markfree:proc
  226.      global  memory_block_lock:proc
  227.      global  memory_block_unlock:proc
  228.      global  memory_block_allocfail:proc
  229.  
  230. memory_block  STRUC METHOD {
  231.  initget:mptr=memory_block_initget   ;  SI returns seg of allocated block.
  232.  init:mptr=memory_block_init         ;  DS:SI is block.
  233.  virtual deinit:mptr=memory_block_deinit
  234.  virtual show:mptr=mb_show
  235.  virtual memstart:mptr=memory_block_reserved_size
  236.  virtual MatchNext:mptr=mb_findprev
  237.  virtual ScanFree:mptr=mb_scan
  238.  virtual GetNext:mptr=mb_getnext
  239.  virtual IsFree:mptr=mb_isfree
  240.  virtual SetPrev:mptr=mb_setprev
  241.  virtual SetNext:mptr=mb_setnext
  242.  virtual SetSize:mptr=mb_setsize
  243.  virtual RawBlockSize:mptr=mb_rawblocksize
  244.  virtual BreakBlock:mptr=mb_breakblock
  245.  virtual MarkUsed:mptr=memory_block_markused
  246.  virtual Combine:mptr=memory_block_combine
  247.  virtual MarkFree:mptr=memory_block_markfree
  248.  virtual LockBlock:mptr=memory_block_lock
  249.  virtual UnLockBlock:mptr=memory_block_unlock
  250.  virtual AllocFail:mptr=memory_block_allocfail
  251. }
  252.  
  253.   TBLPTR
  254.   next   dd   ?      ; Segment of the next block in memory.
  255.                      ;  (Only used as a word. High word set to blank in init.)
  256.                      ; FFFF if this block is unused.
  257.                      ; 0000 if this is the last block.
  258.  
  259. ; Mark this offset to be returned as where the caller can start at
  260. ; using this block of memory.
  261. @memory_block_used_start  label byte
  262.  
  263.   ; The following are only for unused blocks
  264.   next2  dd   ?      ; The segment of the next block if this block is unused.
  265.                      ;  (Only used as a word. High word set to blank in init.)
  266. ifdef _DO_SETPREV_
  267.   prev   dd   ?      ; Segment of the previous block.
  268.                      ;  (Only used as a word. High word set to blank in init.)
  269. endif
  270.   blksize  dw   ?    ; Size of the block in paragraphs.
  271.                      ; This should be the size of the allocateable area,
  272.                      ;   (corrected for the bookkeeping area)
  273.  
  274. memory_block  ends
  275.  
  276.  
  277. ifdef _MAKE_MEMVMT_
  278. ; Make the VMT for the memory blocks
  279. MAKE_VMT
  280. endif
  281.  
  282. ;mbsize = size @TableAddr_MEMORY_BLOCK
  283.  
  284.  
  285. ; memory_usedblock
  286. ;    When a block of memory on the heap is in use, it's VMT is changed
  287. ; so that the block becomes used. The usedblock routines handle returning,
  288. ; in a faster way, the results for various block methods. The block
  289. ; methods for invalid operations on used blocks are quickly trapped,
  290. ; and can even vector to internal_error display routines.
  291. ;    While the normal memory_block routines do extensive checking with the
  292. ; IsFree method, changing used blocks to this type should speed many
  293. ; operations
  294.  
  295.      global memory_usedblock_init:proc
  296.      global memory_usedblock_getnext:proc
  297.      global memory_usedblock_scan:proc
  298.      global memory_usedblock_isfree:proc
  299.      global memory_usedblock_invalid:proc
  300.      global memory_usedblock_setnext:proc
  301.      global memory_usedblock_markfree:proc
  302.      global memory_usedblock_show:proc
  303.      global memory_usedblock_combine:proc
  304.      global memory_usedblock_lock:proc
  305.      global memory_usedblock_unlock:proc
  306.  
  307. memory_usedblock  struc memory_block method {
  308.          init:mptr = memory_usedblock_init
  309.          virtual getnext:mptr=memory_usedblock_getnext
  310.          virtual ScanFree:mptr=memory_usedblock_scan
  311.          virtual IsFree:mptr=memory_usedblock_isfree
  312.          virtual SetPrev:mptr=memory_usedblock_invalid
  313.          virtual SetSize:mptr=memory_usedblock_invalid
  314.          virtual SetNext:mptr=memory_usedblock_setnext
  315.          virtual BreakBlock:mptr=memory_usedblock_invalid
  316.          virtual MarkFree:mptr=memory_usedblock_markfree
  317.          virtual MarkUsed:mptr=memory_usedblock_invalid
  318.          virtual show:mptr = memory_usedblock_show
  319.          virtual Combine:mptr=memory_usedblock_combine
  320.          virtual LockBlock:mptr=memory_usedblock_lock
  321.          virtual UnLockBlock:mptr=memory_usedblock_unlock
  322.         }
  323. memory_usedblock  ends
  324.  
  325.  
  326. ifdef _MAKE_MEMVMT_
  327. ; Make the VMT for the memory usedblocks
  328. MAKE_VMT
  329. endif
  330.  
  331. ; memory_endblock
  332. ;    This block is placed at the end of the memory heap. It should
  333. ; be only a paragraph in size, just large enough for the bookkeeping
  334. ; info of the segment. This allows all other blocks on the heap to
  335. ; be guarranteed that a block follows them, and therefore they can all
  336. ; use simple segment arithmetic to calculate their size. While the
  337. ; size of the memory block can be made a part of the information that
  338. ; is stored for the free blocks, used blocks do not have room for this
  339. ; information. Since the block does not have access to the last segment
  340. ; variable of the heap, the ending block on the heap would have no way
  341. ; to calculate it's size if it is used, since the next pointer would
  342. ; be zero.   This block handles the whole matter, by appearing to be a
  343. ; permanently used block at the end of the heap. Since the next pointer
  344. ; is zero, all heapwalks will stop with this block.
  345.  
  346.      global memory_endblock_init:proc
  347.      global memory_endblock_show:proc
  348.      global memory_endblock_getnext:proc
  349.      global memory_endblock_ignore:proc
  350.  
  351. memory_endblock  struc memory_usedblock method {
  352.          init:mptr = memory_endblock_init
  353.          virtual getnext:mptr = memory_endblock_getnext
  354.          virtual show:mptr = memory_endblock_show
  355.          virtual RawBlockSize:mptr=memory_endblock_getnext
  356.          virtual LockBlock:mptr=memory_endblock_ignore
  357.          virtual UnLockBlock:mptr=memory_endblock_ignore
  358.          }
  359. memory_endblock  ends
  360.  
  361.  
  362. ifdef _MAKE_MEMVMT_
  363. ; Make the VMT for the memory endblocks
  364. MAKE_VMT
  365. endif
  366.  
  367.  
  368. ;  MEMORY_SYSTEM
  369. ;
  370. ;  init -  Handles setting up a block of memory for memory allocation
  371. ;          management.
  372. ;      Arguments: DS:SI - Address of memory system object
  373. ;                 AX    - 0 - Allocate maximum block.
  374. ;                         other - Size of desired block
  375. ;                         High-bit of AX  - If 1 - Allow smaller block
  376. ;                                           If 0 - Fail if not enough memory
  377. ;      Returns:   Memory block initialized.
  378. ;                 DS:SI unchanged.
  379. ;                 AX is size of actual block. (Note that maximum allocateable
  380. ;                       size is a paragraph less than this value because of
  381. ;                       memory_block bookkeeping.)
  382. ;
  383. ;
  384. ; alloc - Allocates an area in the memory block.
  385. ;      Arguments: DS:SI - Address of memory system object
  386. ;                 AX    - Size in bytes of area to allocate
  387. ;      Returns:   AX is segment of memory block
  388. ;                 BX is the offset into the memory block
  389. ;                 DS:SI unchanged
  390. ;                 If no block can be allocated, then AX is zero, and
  391. ;                 BX is the size of the largest block.
  392. ;
  393. ;
  394. ; free -   Frees an allocated area
  395. ;      Arguments: DS:SI - Address of the memory system object
  396. ;                 AX    - Segment of area to be freed
  397. ;      Returns:   None
  398. ;
  399. ;
  400. ; blockofs - Returns fixed offset within memory blocks that marks the
  401. ;            start of information that is only optionally used if the
  402. ;            block is empty. This allows descendants to increase the
  403. ;            amount of bookkeeping information used in the memory_block
  404. ;            for all blocks, free and used.
  405. ;            Users of the memory system only need to store segment
  406. ;            values of alloced blocks, and they can use this function to
  407. ;            fill in the offset if they want.
  408. ;     Arguments: AX  Segment of block to find this value for
  409. ;                    (If AX=0, then root block's blockofs is returned.)
  410. ;     Returns:   AX  with fixed offset value
  411. ;
  412. ;
  413. ; resetrover - Makes rover point at the root block. This causes the
  414. ;            next alloc call to use the earliest possible free
  415. ;            block in the heap.
  416. ;
  417. ;
  418. ;
  419. ; show - Displays global status information for the memory_system, and
  420. ;       then calls the show method for each of the individual memory
  421. ;       blocks.
  422. ;
  423. ;
  424. ; freeall - Frees all blocks on the heap.
  425. ;
  426. ;***** Lower Level Calls:
  427. ;
  428. ;  FindPrev - Finds the address if the block current to the previous block.
  429. ;      Arguments: DS:SI - Address of memory system
  430. ;                 AX    - Segment address of block to find previous for
  431. ;      Returns:   AX    - Segment of previous memory block
  432. ;                         AX=0 if a previous block was not found.
  433. ;                 DS:SI - Unchanged
  434.  
  435. ; This is the global memory system manager object.
  436.  
  437.      global memory_system_init:proc
  438.      global memory_system_deinit:proc
  439.      global memory_system_show:proc
  440.      global memory_system_alloc:proc
  441.      global memory_system_free:proc
  442.      global memory_system_blockofs:proc
  443.      global memory_system_freeall:proc
  444.      global memory_system_resetrover:proc
  445.      global memory_system_findprev:proc
  446.  
  447. memory_system STRUC METHOD {
  448.          init:mptr = memory_system_init
  449.          virtual deinit:mptr=memory_system_deinit
  450.          virtual show:mptr=memory_system_show
  451.          virtual alloc:mptr=memory_system_alloc
  452.          virtual free:mptr=memory_system_free
  453.          blockofs:mptr=memory_system_blockofs
  454.          virtual freeall:mptr=memory_system_freeall
  455.          virtual resetrover:mptr=memory_system_resetrover
  456.          virtual FindPrev:mptr=memory_system_findprev
  457.        }
  458.   TBLPTR
  459.  
  460.   blocksize dw ?     ; Size of the block of memory managed by this
  461.                      ; memory system manager.
  462.   root   dw   ?      ; The first block of memory
  463.   last   dw   ?      ; The last block of memory
  464.   rover  dw   ?      ; Moves through memory
  465.  
  466.   freespace dw ?     ; Remembers the amount of free space total in paragraphs
  467.   usedspace dw ?     ; Remembers the amount of used memory in paragraphs
  468. memory_system ends
  469. ;mssize = size @TableAddr_MEMORY_system
  470.  
  471. ifdef _MAKE_MEMVMT_
  472. ; Make the VMT for the memory endblocks
  473. MAKE_VMT
  474. endif
  475.  
  476.  
  477.